package org.example.scoresystem_backen.service;

import org.example.scoresystem_backen.entity.Score;
import org.example.scoresystem_backen.dto.PageRequest;
import org.example.scoresystem_backen.dto.PageResponse;
import org.example.scoresystem_backen.dto.ScoreDetailDTO;
import org.example.scoresystem_backen.dto.StudentOptionDTO;
import org.example.scoresystem_backen.dto.CourseOptionDTO;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;

/**
 * 成绩服务接口
 */
public interface ScoreService {
    
    /**
     * 创建成绩记录
     * @param score 成绩信息
     * @return 创建的成绩
     */
    Score createScore(Score score);
    
    /**
     * 更新成绩记录
     * @param score 成绩信息
     * @return 更新后的成绩
     */
    Score updateScore(Score score);
    
    /**
     * 删除成绩记录
     * @param id 成绩ID
     */
    void deleteScore(Integer id);
    
    /**
     * 根据ID查找成绩
     * @param id 成绩ID
     * @return 成绩信息
     */
    Score findById(Integer id);
    
    /**
     * 获取所有成绩
     * @return 成绩列表
     */
    List<Score> findAll();
    
    /**
     * 分页查询成绩
     * @param pageable 分页参数
     * @return 成绩分页数据
     */
    Page<Score> findAll(Pageable pageable);
    
    /**
     * 根据学生ID查找成绩
     * @param studentId 学生ID
     * @return 成绩列表
     */
    List<Score> findByStudentId(Integer studentId);
    
    /**
     * 根据课程ID查找成绩
     * @param courseId 课程ID
     * @return 成绩列表
     */
    List<Score> findByCourseId(Integer courseId);
    
    /**
     * 根据学生ID和课程ID查找成绩
     * @param studentId 学生ID
     * @param courseId 课程ID
     * @return 成绩信息
     */
    Score findByStudentIdAndCourseId(Integer studentId, Integer courseId);
    
    /**
     * 根据班级ID查找成绩
     * @param classId 班级ID
     * @return 成绩列表
     */
    List<Score> findByClassId(Integer classId);
    
    /**
     * 根据班级ID和课程ID查找成绩
     * @param classId 班级ID
     * @param courseId 课程ID
     * @return 成绩列表
     */
    List<Score> findByClassIdAndCourseId(Integer classId, Integer courseId);
    
    /**
     * 根据成绩范围查找成绩
     * @param minScore 最低分
     * @param maxScore 最高分
     * @return 成绩列表
     */
    List<Score> findByScoreBetween(BigDecimal minScore, BigDecimal maxScore);
    
    /**
     * 根据考试日期范围查找成绩
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 成绩列表
     */
    List<Score> findByExamDateBetween(LocalDate startDate, LocalDate endDate);
    
    /**
     * 计算学生平均分
     * @param studentId 学生ID
     * @return 平均分
     */
    BigDecimal calculateAverageScoreByStudentId(Integer studentId);
    
    /**
     * 计算课程平均分
     * @param courseId 课程ID
     * @return 平均分
     */
    BigDecimal calculateAverageScoreByCourseId(Integer courseId);
    
    /**
     * 计算班级平均分
     * @param classId 班级ID
     * @return 平均分
     */
    BigDecimal calculateAverageScoreByClassId(Integer classId);
    
    /**
     * 检查学生是否已有该课程成绩
     * @param studentId 学生ID
     * @param courseId 课程ID
     * @return 是否存在
     */
    boolean existsByStudentIdAndCourseId(Integer studentId, Integer courseId);
    
    /**
     * 批量导入成绩
     * @param scores 成绩列表
     * @return 导入结果
     */
    List<Score> batchImportScores(List<Score> scores);

    // ========== 分页查询相关方法 ==========

    /**
     * 分页查询成绩详情（管理员权限）
     * @param pageRequest 分页请求参数
     * @return 分页响应结果
     */
    PageResponse<ScoreDetailDTO> findScoreDetailsWithPagination(PageRequest pageRequest);

    /**
     * 分页查询学生成绩详情（学生权限）
     * @param studentId 学生ID
     * @param pageRequest 分页请求参数
     * @return 分页响应结果
     */
    PageResponse<ScoreDetailDTO> findScoreDetailsByStudentIdWithPagination(Integer studentId, PageRequest pageRequest);

    // ========== 增强的CRUD操作 ==========

    /**
     * 创建成绩记录（增强版，包含数据验证）
     * @param score 成绩信息
     * @return 创建的成绩
     * @throws RuntimeException 当数据验证失败时
     */
    Score createScoreWithValidation(Score score);

    /**
     * 更新成绩记录（增强版，包含冲突检查）
     * @param score 成绩信息
     * @return 更新后的成绩
     * @throws RuntimeException 当记录不存在或冲突时
     */
    Score updateScoreWithValidation(Score score);

    /**
     * 删除成绩记录（增强版，包含存在性验证）
     * @param id 成绩ID
     * @throws RuntimeException 当记录不存在时
     */
    void deleteScoreWithValidation(Integer id);

    // ========== 选项查询相关方法 ==========

    /**
     * 获取学生选项列表（用于下拉选择）
     * @return 学生选项列表
     */
    List<StudentOptionDTO> getStudentOptions();

    /**
     * 获取课程选项列表（用于下拉选择）
     * @return 课程选项列表
     */
    List<CourseOptionDTO> getCourseOptions();

    // ========== 权限验证相关方法 ==========

    /**
     * 验证学生是否有权限访问指定成绩
     * @param studentId 学生ID
     * @param scoreId 成绩ID
     * @return 是否有权限
     */
    boolean hasPermissionToAccessScore(Integer studentId, Integer scoreId);

    /**
     * 验证成绩数据的有效性
     * @param score 成绩对象
     * @throws RuntimeException 当数据无效时
     */
    void validateScoreData(Score score);
}
